<?php
/**
 * @Notes:【】
 * @Date: 2022-06-23 0:14
 */

namespace Yj\Providers;

use Hyperf\Database\Model\Builder;
use Yj\Core\ServiceProvider;
use Yj\Providers\Builder\WhereHasIn;
use Yj\Tool\Carbon;


class BuilderProvider extends ServiceProvider
{
    public function boot()
    {
        Builder::macro('whereHasIn', function ($relationName, $callable = null) {
            return (new WhereHasIn($this, $relationName, function ($nextRelation, $builder) use ($callable) {
                if ($nextRelation) {
                    return $builder->whereHasIn($nextRelation, $callable);
                }
                if ($callable) {
                    $callScope = $builder->callScope($callable);
                    return $callScope;
                }
                return $builder;
            }))->execute();
        });
//        Builder::macro('whereHasJoin', function ($relationName, $callable = null) {
//            return (new WhereHasJoin($this, $relationName, function (Builder $builder, Builder $relationBuilder) use ($callable) {
//                if ($callable) {
//                    $relationBuilder->callScope($callable);
//                    return $builder->addNestedWhereQuery($relationBuilder->getQuery());
//                }
//                return $builder;
//            }))->execute();
//        });
//
//        Builder::macro('orWhereHasIn', function ($relationName, $callable = null) {
//            return $this->orWhere(function ($query) use ($relationName, $callable) {
//                return $query->whereHasIn($relationName, $callable);
//            });
//        });
//        Builder::macro('whereHasNotIn', function ($relationName, $callable = null) {
//            return (new WhereHasNotIn($this, $relationName, function ($nextRelation, $builder) use ($callable) {
//                if ($nextRelation) {
//                    return $builder->whereHasNotIn($nextRelation, $callable);
//                }
//
//                if ($callable) {
//                    return $builder->callScope($callable);
//                }
//
//                return $builder;
//            }))->execute();
//        });
//        Builder::macro('orWhereHasNotIn', function ($relationName, $callable = null) {
//            return $this->orWhere(function ($query) use ($relationName, $callable) {
//                return $query->whereHasNotIn($relationName, $callable);
//            });
//        });
//
//        Builder::macro('yjwhere', function ($column, $operator = null, $value = null, $boolean = 'and') {
//            return $this->where($this->getModel()->getTable() . '.' . $column, $operator, $value, $boolean);
//        });
//
//        Builder::macro('yjwhereIn', function ($column, $values, $boolean = 'and', $not = false) {
//            return $this->whereIn($this->getModel()->getTable() . '.' . $column, $values, $boolean = 'and', $not = false);
//        });
//
//        Builder::macro('yjwhereBetween', function ($column, array $values, $boolean = 'and', $not = false) {
//            return $this->whereBetween($this->getModel()->getTable() . '.' . $column, $values, $boolean, $not);
//        });
//
//        Builder::macro('yjselect', function ($columns = ['*']) {
//            $table = $this->getModel()->getTable();
//            $columns = is_array($columns) ? $columns : func_get_args();
//            foreach ($columns as &$column) {
//                $column = $table . '.' . $column;
//            }
//            return $this->select($columns);
//        });
//
//        Builder::macro('yjOrderBy', function ($column, $direction = 'asc') {
//            return $this->orderBy($column, $direction);
//        });
//        Builder::macro('yjOrderByDesc', function ($column) {
//            return $this->orderBy($column, 'desc');
//        });
//
//        Builder::macro('whereHasMorphIn', WhereHasMorphIn::make());
//        Builder::macro('orWhereHasMorphIn', function ($relation, $types, $callback = null) {
//            return $this->whereHasMorphIn($relation, $types, $callback, 'or');
//        });

//        Builder::macro('')

        Builder::macro('yjRangeTime', function ($field, $types) {
            $now = Carbon::now();
            switch (['today' => 0, 'yesterday' => -1][$types] ?? $types) {
                case 'month':
                    $startTime = $now->clone()->startOfMonth();
                    $endTime = $now->endOfMonth();
                    break;
                case "last_month" :
                    $startTime = $now->subMonth()->clone()->startOfMonth();
                    $endTime = $now->endOfMonth();
                    break;
                case "year" :
                    $startTime = $now->clone()->startOfYear();
                    $endTime = $now->endOfYear();
                    break;
                case "last_year" :
                    $startTime = $now->subYear()->clone()->startOfYear();
                    $endTime = $now->endOfYear();
                    break;
                default:
                    $startTime = $now->subDays((int)$types)->clone()->startOfDay();
                    $endTime = $now->endOfDay();
            }
            return $this->whereBetween($field, [$startTime->timestamp, $endTime->timestamp]);
        });

    }

    /**
     * 搜索时间转换
     * @param $timeKey
     * @param false $isNum
     * @return array
     * @throws \Exception
     */
    public function TimeConvert($timeKey, $isNum = false)
    {
        switch ($timeKey) {
            case "today" :
                $data['start_time'] = date('Y-m-d 00:00:00', time());
                $data['end_time'] = date('Y-m-d 23:59:59', time());
                $data['days'] = 1;
                break;
            case "yestoday" :
                $data['start_time'] = date('Y-m-d 00:00:00', strtotime('-1 day'));
                $data['end_time'] = date('Y-m-d 23:59:59', strtotime('-1 day'));
                $data['days'] = 1;
                break;
            case "last_month" :
                $data['start_time'] = date('Y-m-01 00:00:00', strtotime('-1 month'));
                $data['end_time'] = date('Y-m-t 23:59:59', strtotime('-1 month'));
                $data['days'] = 30;
                break;
            case "month" :
                $data['start_time'] = $month_start_time = date('Y-m-01 00:00:00', strtotime(date("Y-m-d")));
                $data['end_time'] = date('Y-m-d 23:59:59', strtotime("$month_start_time +1 month -1 day"));
                $data['days'] = 30;
                break;
            case "year" :
                $data['start_time'] = date('Y-01-01 00:00:00', time());
                $data['end_time'] = date('Y-12-t 23:59:59', time());
                $data['days'] = 365;
                break;
            case "last_year" :
                $data['start_time'] = date('Y-01-01 00:00:00', strtotime('-1 year'));
                $data['end_time'] = date('Y-12-t 23:59:59', strtotime('-1 year'));
                $data['days'] = 365;
                break;
            case 30 :
            case 15 :
            case 7 :
                if (!$isNum) {
                    $data['start_time'] = date("Y-m-d 00:00:00", strtotime("-$timeKey day"));
                    $data['end_time'] = date('Y-m-d 23:59:59', time());
                    $data['days'] = $timeKey;
                } else {
                    $day = $timeKey * 2;
                    $data['start_time'] = date("Y-m-d 00:00:00", strtotime("-$day  day"));
                    $data['end_time'] = date("Y-m-d 23:59:59", strtotime("-$timeKey day"));
                    $data['days'] = $timeKey;
                }
                break;
            default:
                $datetime_start = new \DateTime($timeKey['start_time']);
                $datetime_end = new \DateTime($timeKey['end_time']);
                $days = $datetime_start->diff($datetime_end)->days;
                $days = $days > 0 ? $days : 1;
                if (!$isNum) {
                    $data['start_time'] = $timeKey['start_time'];
                    $data['end_time'] = $timeKey['end_time'];
                    $data['days'] = $days;
                } else {
                    $data['start_time'] = date("Y-m-d 00:00:00", strtotime("-$days day"));
                    $data['end_time'] = $timeKey['start_time'];
                    $data['days'] = $days;
                }

        }

        return $data;
    }


}